package com.ltw.dreamer.stock.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.ltw.dreamer.common.network.WebPageReader;
import com.ltw.dreamer.common.util.DateUtil;
import com.ltw.dreamer.stock.mapper.StockInfoMapper;
import com.ltw.dreamer.stock.model.Stock;
import com.ltw.dreamer.stock.model.StockInfo;
import com.ltw.dreamer.stock.model.StockInfoExample;
import com.ltw.dreamer.stock.model.StockInfoExample.Criteria;
import com.ltw.dreamer.stock.service.StockInfoService;
import com.ltw.dreamer.stock.util.StockInfoUtil;

@Service
public class StockInfoServiceImpl implements StockInfoService {
	public static final Logger LOGGER = Logger.getLogger(StockInfoServiceImpl.class);
	
	@Resource
	private StockInfoMapper mapper = null;
	
	@Resource
	private WebPageReader reader = null;
	
	public void updateStockDailyInfo(Stock stock) {
		String serviceUrlStr = getServiceUrlStr(stock);
		if (serviceUrlStr == null) return;
		
		StockInfo stockInfo = new StockInfo();
		stockInfo.setCode(stock.getCode());
		
		String content = reader.read(serviceUrlStr);
		if (!loadStockInfo(stockInfo, content)) return;
		
		cleanStockOldValueOfToday(stockInfo);
		mapper.insert(stockInfo);
	}

	private void cleanStockOldValueOfToday(StockInfo stockInfo) {
		StockInfoExample example = new StockInfoExample();
		Criteria criteria = example.createCriteria();
		criteria.andCodeEqualTo(stockInfo.getCode());
		criteria.andDateEqualTo(stockInfo.getDate());
		mapper.deleteByExample(example);
	}
	
	public void cleanDuplicatedData(Stock stock) {
		if (stock == null || stock.getCode() == null)
			throw new IllegalArgumentException("入参错误.");
		List<StockInfo> allData = queryAllData(stock);
		
		Set<String> dateStamp = new HashSet<String>();
		for (StockInfo stockInfo : allData) {
			String dateStr = DateUtil.getDailyDateString(stockInfo.getDate());
			if (dateStamp.contains(dateStr)) {
				removeStockInfo(stockInfo);
				continue;
			}
			
			dateStamp.add(dateStr);
		}
	}
	
	public void cleanClosedDayData(Stock stock) {
		StockInfoExample example = new StockInfoExample();
		Criteria criteria = example.createCriteria();
		// criteria.andExchangeRateEqualTo(0.00);
		criteria.andExchangeRateIsNull();
		mapper.deleteByExample(example);
	}
	
	private List<StockInfo> queryAllData(Stock stock) {
		StockInfoExample example = new StockInfoExample();
		Criteria criteria = example.createCriteria();
		criteria.andCodeEqualTo(stock.getCode());
		example.setOrderByClause("datetime");
		
		return mapper.selectByExample(example);
	}

	
	private void removeStockInfo(StockInfo stockInfo) {
		mapper.deleteByPrimaryKey(stockInfo.getId());
	}

	private String getServiceUrlStr(Stock stock) {
		String stockCode = stock.getCode();
		String marketCode = stock.getMarketCode();
		if (stockCode == null || marketCode == null) {
			LOGGER.warn("股票基本信息表配置错误，请确认问题." + stock.toString());
			return null;
		}
		
		LOGGER.info("开始处理股票基础信息，股票代码：" + stockCode);
		return "http://qt.gtimg.cn/q=" + marketCode.trim() + stockCode.trim();
	}
	private boolean loadStockInfo(StockInfo stock, String content) {
		if (content == null) {
			LOGGER.info("出现内部错误，请检查当前股票信息是否正常。");
			return false;
		}
		
		if (!StockInfoUtil.compile(content)) {
			// LOGGER.info("查询股票信息时失败，可能股票状态异常。");
			return false;
		}
		
		String stockInfoStr = StockInfoUtil.getValue();
		String[] data = stockInfoStr.split("~");
		loadStockInfo(stock, data);
		if (stock.getExchangeRate()==null || stock.getExchangeRate() == 0.00) return false;
		return true;
	}

	private void loadStockInfo(StockInfo stock, String[] data) {
		if (data == null || data.length != 49) {
			LOGGER.info("股票基础信息内容有误，请确认接口是否有变化。");
			return ;
		}
		
		stock.setName(getStringValue(data[1]));
		stock.setCurPrice(getDoubleValue(data[3]));
		stock.setYesPrice(getDoubleValue(data[4]));
		stock.setTodOpenPrice(getDoubleValue(data[5]));
		stock.setCount(getDoubleValue(data[6]));
		stock.setOutCount(getDoubleValue(data[7]));
		stock.setInnerCount(getDoubleValue(data[8]));
		stock.setBuyOneCount(getDoubleValue(data[9]));
		
		stock.setBuyOnePrice(getDoubleValue(data[10]));
		stock.setBuyTwoCount(getDoubleValue(data[11]));
		stock.setBuyTwoPrice(getDoubleValue(data[12]));
		stock.setBuyThreeCount(getDoubleValue(data[13]));
		stock.setBuyThreePrice(getDoubleValue(data[14]));
		stock.setBuyFourCount(getDoubleValue(data[15]));
		stock.setBuyFourPrice(getDoubleValue(data[16]));
		stock.setBuyFiveCount(getDoubleValue(data[17]));
		stock.setBuyFivePrice(getDoubleValue(data[18]));
		stock.setSellOnePrice(getDoubleValue(data[19]));
		
		stock.setSellOneCount(getDoubleValue(data[20]));
		stock.setSellTwoPrice(getDoubleValue(data[21]));
		stock.setSellTwoCount(getDoubleValue(data[22]));
		stock.setSellThreePrice(getDoubleValue(data[23]));
		stock.setSellThreeCount(getDoubleValue(data[24]));
		stock.setSellFourPrice(getDoubleValue(data[25]));
		stock.setSellFourCount(getDoubleValue(data[26]));
		stock.setSellFivePrice(getDoubleValue(data[27]));
		stock.setSellFiveCount(getDoubleValue(data[28]));
		stock.setLastDeal(getStringValue(data[29]));
		
		stock.setDataTime(getDateValue(data[30]));
		stock.setFluctuate(getDoubleValue(data[31]));
		stock.setFluctuatePercent(getDoubleValue(data[32]));
		stock.setTopPrice(getDoubleValue(data[33]));
		stock.setLowPrice(getDoubleValue(data[34]));
		stock.setFeatures(getStringValue(data[35]));
		stock.setTotalCount(getDoubleValue(data[36]));
		stock.setTotalAmount(getDoubleValue(data[37]));
		stock.setExchangeRate(getDoubleValue(data[38]));
		stock.setPer(getDoubleValue(data[39]));

		stock.setTopPrice2(getDoubleValue(data[41]));
		stock.setLowPrice2(getDoubleValue(data[42]));
		stock.setAmplitude(getDoubleValue(data[43]));
		stock.setFlowValues(getDoubleValue(data[44]));
		stock.setTotalValues(getDoubleValue(data[45]));
		stock.setPb(getDoubleValue(data[46]));
		stock.setMaxPrice(getDoubleValue(data[47]));
		stock.setMinPrice(getDoubleValue(data[48]));
		
		stock.setDate(getDateValue(data[30]));
		stock.setDatetime(Calendar.getInstance().getTime());
	}
	private String getStringValue(String oriStr) {
		if (oriStr == null || oriStr.trim().length() == 0) return "";
		return oriStr.trim();
	}

	private Double getDoubleValue(String oriStr) {
		if (oriStr == null || oriStr.trim().length() == 0) return null;
		Double value = new Double(oriStr.trim());
		return value;
	}
	

	private Date getDateValue(String oriStr) {
		if (oriStr == null || oriStr.trim().length() == 0) return null;
		Date date = null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
			date = sdf.parse(oriStr);
		} catch (ParseException e) {
			LOGGER.info("股票信息时间解析出现错误。" + e.getLocalizedMessage());
		}
		return date;
	}
	public StockInfo queryStockInfo(Stock stock) {
		if (stock.getDate() == null) return null;
		StockInfoExample example = new StockInfoExample();
		Criteria criteria = example.createCriteria();
		criteria.andCodeEqualTo(stock.getCode());
		criteria.andDateEqualTo(stock.getDate());
		example.setOrderByClause("date desc");
		
		List<StockInfo> resultList = mapper.selectByExample(example);
		if (resultList == null || resultList.size() == 0) return null;
		
		return resultList.get(0);
	}
	
	public List<StockInfo> queryStockInfo(String stockCode) {
		if (stockCode == null)
			throw new IllegalArgumentException(stockCode);
		
		StockInfoExample example = new StockInfoExample();
		Criteria criteria = example.createCriteria();
		criteria.andCodeEqualTo(stockCode);
		example.setOrderByClause("date desc");
		
		return mapper.selectByExample(example);
	}
}
